/*
 * @lc app=leetcode.cn id=8 lang=golang
 * @lcpr version=30118
 *
 * [8] 字符串转换整数 (atoi)
 */

// @lcpr-template-start

// @lcpr-template-end
// @lc code=start

type State int

const (
	START State = iota
	NUM
	END
	UNDEFINED
)

func myAtoi(s string) int {

	res := int64(0)
	neg := false

	state := UNDEFINED

	for i := 0; i < len(s) && res < (int64(1)<<32) && state != END; i++ {
		switch s[i] {
		case '-':
			fallthrough
		case '+':
			switch state {
			case NUM:
				state = END
			case START:
				return 0
			default:
				state = START
				if s[i] == '-' {
					neg = true
				}
			}
		default:
			if s[i] >= '0' && s[i] <= '9' {
				state = NUM
				res = res*10 + int64(s[i]-'0')
			} else if s[i] != ' ' {
				switch state {
				case NUM:
					state = END
				default:
					return 0
				}
			} else {
				switch state {
				case NUM:
					state = END
				case START:
					return 0
				default:
				}
			}
		}
	}
	if neg {
		res = -res
	}
	if res > (int64(1)<<31)-1 {
		res = (int64(1) << 31) - 1
	} else if res < -(int64(1) << 31) {
		res = -(int64(1) << 31)
	}
	return int(res)
}

// @lc code=end

/*
// @lcpr case=start
// "42"\n
// @lcpr case=end

// @lcpr case=start
// "   -42"\n
// @lcpr case=end

// @lcpr case=start
// "4193 with words"\n
// @lcpr case=end

*/

